home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / OPXMS114.ARJ / OPXMS.DOC < prev    next >
Text File  |  1992-07-29  |  16KB  |  408 lines

  1.                                   OPXMS.DOC
  2.                              TurboPower Software
  3.                                   July 1992
  4.  
  5. Of the three modules in Object Professional that provide memory management
  6. (OPEMS, OPEXTMEM, and OPXMS), OPXMS is often the best choice because of its
  7. many special features. These features include the ability to lock blocks of
  8. memory, use the High Memory Area, take advantage of Upper Memory Blocks, and
  9. associate handles with blocks of memory.
  10.  
  11. Locking allocated extended memory blocks assures that they will not be moved
  12. by the XMS memory manager. OPXMS includes functions to lock and unlock blocks
  13. of extended memory, and to get information about the memory blocks.
  14.  
  15. The High Memory Area (HMA) is a 64KB region of memory that Microsoft
  16. "discovered" when they were developing Windows/286. It was given this special
  17. name because it exists in the extended memory, but unlike the rest of extended
  18. memory, it can be directly accessed without being in protected mode. This is
  19. accomplished by enabling the CPU's A20 line, which allows the generation of
  20. 21-bit physical addresses. OPXMS includes functions that allow you to enable,
  21. disable, and query the state of the A20 line. RequestHMA and ReleaseHMA allow
  22. you to allocate and deallocate memory in the HMA.
  23.  
  24. Some XMS memory managers support functions to allocate and free Upper Memory
  25. Blocks (UMBs). UMBs are areas of memory located above the 640K of DOS
  26. accessible memory and below the 1 megabyte boundary. This memory is generally
  27. only accessible under '386 extended memory managers. OPXMS contains functions
  28. to allocate and free UMBs.
  29.  
  30. OPXMS also contains functions that determine whether XMS memory is installed
  31. and, if so, how much is currently available. You can allocate/deallocate and
  32. access blocks of extended memory by taking the following steps:
  33.  
  34. 1. Find out how much extended memory is available by calling QueryFreeExtMem.
  35. 2. If the available memory is sufficient, use AllocateExtMem to allocate the
  36.    required amount.
  37. 3. Once the memory is allocated, use MoveExtMemBlock to move data from normal
  38.    RAM to extended memory and back again.
  39. 4. To dispose of a block of extended memory, call FreeExtMem.
  40.  
  41. AllocateExtMem allows you to allocate memory only in 1K blocks (1,024 bytes).
  42. This makes extended memory less convenient to use for general purpose storage,
  43. but it also means that you can allocate several megabytes of contiguous memory
  44. with a single call to AllocateExtMem.
  45.  
  46. Another important memory management issue is that the MoveExtMemBlock
  47. function, which is used to transfer data between normal and extended memory,
  48. does not allow you to move data in bytes, only in words (two bytes). This
  49. means that you must be especially careful when defining your data structures,
  50. and that you will sometimes need to pad data structures with dummy bytes to
  51. ensure that their sizes are even numbers. The one benefit of this restriction
  52. is that you can move up to 128K of contiguous data with a single call to
  53. MoveExtMem.
  54.  
  55. Reference Section
  56. -----------------
  57.  
  58. Types
  59.  
  60.   ExtMemPtr =
  61.     record
  62.       case Boolean of
  63.         False : (RealPtr : Pointer);
  64.         True  : (ProtectedPtr : LongInt);
  65.     end;
  66.  
  67. A data structure used to specify pointers to either conventional or extended
  68. memory. In conventional memory, pointers are normal Segment:Offset pointers.
  69. In protected memory, linear addresses (longints) are used. This type is used
  70. only for the MoveExtMemBlock and LockExtMemBlock functions.
  71.  
  72. Variables
  73.  
  74.   XmsControl : Pointer;
  75.  
  76. Stores a pointer to the XMS control function. This is intended primarily
  77. for internal use.
  78.  
  79. Error Codes
  80.  
  81. The following lists all error codes that can be returned from the XMS
  82. functions:
  83.  
  84.   $00   Success
  85.   $80   Function not implemented
  86.   $81   VDISK device driver was detected
  87.   $82   A20 error occurred
  88.   $8E   General driver error
  89.   $8F   Unrecoverable driver error
  90.   $90   High memory area does not exist
  91.   $91   High memory area already in use
  92.   $92   Size requested is less than /HMAMIN=parameter
  93.   $93   High memory area not allocated
  94.   $94   A20 line is still enabled
  95.   $A0   All extended memory is allocated
  96.   $A1   Extended memory handles exhausted
  97.   $A2   Invalid handle
  98.   $A3   Invalid source handle
  99.   $A4   Invalid source offset
  100.   $A5   Invalid destination handle
  101.   $A6   Invalid destination offset
  102.   $A7   Invalid length
  103.   $A8   Invalid overlap in move request
  104.   $A9   Parity error detected
  105.   $AA   Block is not locked
  106.   $AB   Block is locked
  107.   $AC   Lock count overflowed
  108.   $AD   Lock failed
  109.   $B0   Smaller UMB is available
  110.   $B1   No UMBs are available
  111.   $B2   Invalid UMB segment number
  112.  
  113. Declaration
  114.   function AllocateExtMem(SizeInK : Word; var XmsHandle : Word) : Byte;
  115. Purpose
  116.  Allocate a block of extended memory.
  117. Description
  118.  This function allocates a block of extended memory SizeInK kilobytes in
  119.  size, and returns the XMS handle in XMSHandle. A status code is returned
  120.  in the function result.
  121. Example
  122.   var
  123.     Handle : Word;
  124.     Res : Byte;
  125.   begin
  126.     Res := AllocateExtMem(256, Handle);
  127.     if Res <> 0 then
  128.       WriteLn('Cannot allocate XMS memory. Result: ' Res);
  129.   end;
  130.  
  131.  Tries to allocate 256k of extended memory and prints the error code if not
  132.  successful.
  133. See Also
  134.  FreeExtMem
  135.  
  136. Declaration
  137.   function AllocUpperMemBlock(SizeInParas : Word; var SegmentBase : Word;
  138.                               var Size : Word) : Byte;
  139. Purpose
  140.  Allocate an upper memory block (UMB).
  141. Description
  142.  If this function succeeds, SegmentBase contains the segment of the allocated
  143.  upper memory block and Size contains the size (in kilobytes) of the block. If
  144.  insufficient memory is available for the requested upper memory block, then
  145.  the size of the largest free upper memory block is returned in Size.
  146.  
  147.  Upper memory blocks are paragraph aligned (the offset is always 0). By
  148.  definition, UMBs are located below the 1 megabyte address boundary, therefore
  149.  there is no need to enable the A20 line to access the memory in a UMB. There
  150.  are no restrictions on using this memory in DOS calls or pointing ISRs into
  151.  this memory.
  152.  
  153.  This function is not implemented by most '286 XMS drivers. It is implemented
  154.  by most '386 memory managers such as QEMM, 386MAX, and EMM386.
  155. See also
  156.  FreeUpperMemBlock
  157.  
  158. Declaration
  159.  function FreeExtMem(XmsHandle : Word) : Byte;
  160. Purpose
  161.  Free a block of extended memory.
  162. Description
  163.  XMSHandle is the XMS handle returned by the previous call to AllocateExtMem.
  164.  Note that this function must be called to free any allocated blocks of
  165.  extended memory before a program terminates (it is not done automatically).
  166.  Otherwise, they remain allocated and subsequent programs are not able to use
  167.  them.
  168. Example
  169.   var
  170.     Handle : Word;
  171.   begin
  172.     if AllocateExtMem(256, Handle) = 0) then begin
  173.       if FreeExtMem(Handle) <> 0
  174.         WriteLn('Unable to free XMS');
  175.     end
  176.     else
  177.       WriteLn('Unable to allocate XMS');
  178.  
  179.  First tries to allocate 256K of extended memory and then attempts to free it,
  180.  printing error messages if either fails.
  181. See Also
  182.  AllocateExtMem
  183.  
  184. Declaration
  185.  function FreeUpperMemBlock(SegmentBase : Word) : Byte;
  186. Purpose
  187.  Free an allocated upper memory block.
  188. Description
  189.  This function frees a UMB that was allocated by AllocUpperMemBlock. If
  190.  SegmentBase does not refer to a valid UMB, an error code $82 is returned.
  191. See Also
  192.  AllocUpperMemBlock
  193.  
  194. Declaration
  195.  function GetHandleInfo(XmsHandle : Word; var LockCount, var HandlesLeft : Byte;
  196.                         var BlockSizeInK : Word) : Byte;
  197. Purpose
  198.  Return information about a block associated with an extended memory handle.
  199. Description
  200.  This function returns the lock count for this handle, the number of XMS
  201.  handles left, and the size in kilobytes of the block associated with this
  202.  handle. If you also need the 32 bit linear address of this handle, you must
  203.  call LockExtMemBlock.
  204. See Also
  205.  AllocateExtMem LockExtMemBlock
  206.  
  207. Declaration
  208.  function GlobalDisableA20 : Byte;
  209. Purpose
  210.  Attempt to disable the A20 line.
  211. Description
  212.  This function disables 21-bit physical addressing. If you enabled the A20
  213.  line, it should be disabled by calling GlobalDisableA20 before exiting your
  214.  program.
  215. See Also
  216.  GlobalEnableA20 QueryA20
  217.  
  218. Declaration
  219.  function GlobalEnableA20 : Byte;
  220. Purpose
  221.  Attempt to enable the A20 line.
  222. Description
  223.  This function enables 21-bit physical addressing. It should be used only by
  224.  programs that own the HMA. However, since both DOS 5.0 and Windows can make
  225.  more efficient use of the HMA than your application, this function is
  226.  probably not needed.
  227. See also
  228.  GlobalDisableA20 QueryA20
  229.  
  230. Declaration
  231.  function LockExtMemBlock(XmsHandle : Word; var LockedBlock : ExtMemPtr) : Byte;
  232. Purpose
  233.  Lock an extended memory block and return its base address as a 32 bit linear
  234.  address.
  235. Description
  236.  This function locks an extended memory block, thus preventing it from being
  237.  moved. XMSHandle must be a valid handle for a previously allocated block of
  238.  memory (for example, a handle returned by AllocateExtMem). The LockedBlock
  239.  address is valid only while the block is locked. Locked extended memory
  240.  blocks should be unlocked as soon as possible. It is not necessary to lock a
  241.  block before calling MoveExtMemBlock. A count of the number of locks is
  242.  maintained by the XMS memory manager and can be retrieved with the
  243.  GetHandleInfo function.
  244. See Also
  245.  GetHandleInfo UnlockExtMemBlock
  246.  
  247. Declaration
  248.  function MoveExtMemBlock(BlockLength : LongInt;
  249.                           SourceHandle : Word; SourcePtr : ExtMemPtr;
  250.                           DestHandle : Word; DestPtr : ExtMemPtr) : Byte;
  251. Purpose
  252.  Move a block of memory.
  253. Description
  254.  This function is intended primarily for moving data between extended memory
  255.  and conventional memory, however it can also move memory from extended to
  256.  extended and conventional to conventional.
  257.  
  258.  BlockLength is the number of bytes to move. It must always be an even number
  259.  because MoveExtMemBlock deals in words. Memory areas may overlap only if
  260.  SourcePtr is at a lower address than DestPtr. If SourceHandle is 0, then
  261.  SourcePtr is interpreted as a normal segment:offset pointer. If SourceHandle
  262.  is non-zero, then SourcePtr is interpreted as a 32 bit linear offset into the
  263.  block of extended memory associated with SourceHandle. The same is true for
  264.  DestHandle and DestPtr. This function does not require that the A20 line be
  265.  enabled. It is not necessary to lock extended memory blocks used as SourcePtr
  266.  or DestPtr.
  267. Examples
  268.  var
  269.    Handle : Word;
  270.    P, XP : ExtMemPtr;
  271.  ...
  272.    GetMem(P.RealPtr, 32768);      {Get 32k}
  273.    if (P.RealPtr <> nil) then
  274.     if (AllocateExtMem(32, Handle) = 0) then begin
  275.       XP.ProtectedPtr := 0;
  276.       if MoveExtMemBlock(32768,         {32 * 1024 bytes}
  277.                          0,             {No handle - use pointer}
  278.                          P,             {Conventional mem pointer}
  279.                          Handle,        {XMS handle}
  280.                          XP) <> 0 then  {0 offset - start at beginning}
  281.         WriteLn('Unable to move block');
  282.     end
  283.     else
  284.       WriteLn('Unable to allocate XMS');
  285.  
  286.  This example attempts to allocate 32K of conventional memory on the heap. If
  287.  successful, another 32K block of XMS memory is allocated. If that operation
  288.  is successful, data is moved from the conventional block to the XMS block.
  289.  Moving from XMS to conventional memory is simply the reverse operation:
  290.  
  291.       XP.ProtectedPtr := 0;
  292.       if MoveExtMemBlock(32768,        {32 * 1024 bytes}
  293.                          Handle,       {XMS handle}
  294.                          XP,           {0 offset - start at beginning}
  295.                          0,            {No handle - use pointer}
  296.                          P) <> 0 then  {Conventional mem pointer}
  297.         WriteLn('Unable to move block');
  298.  
  299.  Moving data from one block to another is also a simple operation:
  300.  
  301.   var
  302.     Handle1, Handle2 : Word;
  303.   ...
  304.     if ((AllocateExtMem(256, Handle1) = 0) and
  305.         (AllocateExtMem(256, Handle2) = 0)) then begin
  306.       XP.ProtectedPtr := 0;
  307.       if (MoveExtMemBlock(32768, Handle1, XP, Handle2, XP) <> 0) then
  308.         WriteLn('Unable to move block');
  309.     end
  310.     else
  311.       WriteLn('Unable to allocate XMS');
  312.  
  313. Declaration
  314.  function QueryA20 : Byte;
  315. Purpose
  316.  Determine if the A20 line is physically enabled.
  317. Description
  318.  QueryA20 returns 0 if the A20 line is disabled, 1 if it is enabled, or one of
  319.  the codes described in "Error Codes" at the beginning of this section if an
  320.  error occurs.
  321. See Also
  322.  GlobalDisableA20 GlobalEnableA20
  323.  
  324. Declaration
  325.  function QueryFreeExtMem(var TotalFree, LargestBlock : Word) : Byte;
  326. Purpose
  327.  Return total amount of free extended memory and the size of the largest free
  328.  block.
  329. Description
  330.  This function returns the total amount of free extended memory in TotalFree,
  331.  and the size of the largest free block of extended memory in LargestBlock.
  332.  Both values are specified in kilobytes.
  333. Example
  334.   var
  335.     TotalFree, LargestBlock, Handle : Word;
  336.   ...
  337.     QueryFreeExtMem(TotalFree, LargestBlock);
  338.     if (LargestBlock >= 1024) then begin
  339.       if AllocateExtMem(1024, Handle) <> 0 then
  340.         WriteLn('Unable to allocate XMS');
  341.     end
  342.     else
  343.       WriteLn('Cannot allocate as one block');
  344.  
  345.  Checks to see if a 1M block of XMS memory is available, and, if so, allocates
  346.  it.
  347.  
  348. Declaration
  349.  function ReleaseHMA : Byte;
  350. Purpose
  351.  Release storage in the High Memory Area.
  352. Description
  353.  This function releases storage in the HMA that was allocated by RequestHMA.
  354.  You must release the HMA before exiting your program.
  355. See Also
  356.  RequestHMA
  357.  
  358. Declaration
  359.  function RequestHMA(Bytes : Word) : Byte;
  360. Purpose
  361.  Request storage in the High Memory Area.
  362. Description
  363.  This function allocates storage in the HMA. Bytes is the minimum amount of
  364.  HMA storage needed by the program. If RequestHMA succeeds, the entire HMA is
  365.  allocated to the calling program.
  366.  
  367.  Note that since both DOS 5.0 and Windows can use the HMA more effectively
  368.  than most application programs, this function is not normally used.
  369. See also
  370.  ReleaseHMA
  371.  
  372. Declaration
  373.  function ResizeExtMemBlock(XmsHandle : Word; NewSizeInK : Word) : Byte;
  374. Purpose
  375.  Attempt to resize the memory block associated with XMSHandle.
  376. Description
  377.  The extended memory block must be unlocked. If NewSizeInK is larger than the
  378.  old size, then all data is preserved. If it is smaller, then all data beyond
  379.  the end of the new block size is lost.
  380. See Also
  381.  AllocateExtMem UnlockExtMemBlock
  382.  
  383. Declaration
  384.  function UnlockExtMemBlock(XmsHandle : Word) : Byte;
  385. Purpose
  386.  Unlock an extended memory block.
  387. Description
  388.  The 32 bit linear address obtained by calling LockExtMemBlock is invalid
  389.  after UnlockExtMemBlock is called.
  390. See Also
  391.  LockExtMemBlock
  392.  
  393. Declaration
  394.  function XmsErrorString(ErrorCode : Byte) : String;
  395. Purpose
  396.  Return an error string for the specified error code.
  397. Description
  398.  This function is passed a valid XMS error code and returns the corresponding
  399.  error string. See "Error Codes," above, for a list of the error codes and
  400.  associated strings.
  401.  
  402. Declaration
  403.  function XmsInstalled : Boolean;
  404. Purpose
  405.  Return True if an XMS memory manager is installed.
  406. Description
  407.  This function is used to determine whether an XMS driver is installed.
  408.